package org.example.scoresystem_backen.service.impl;

import org.example.scoresystem_backen.entity.Student;
import org.example.scoresystem_backen.dto.StudentWithClassDTO;
import org.example.scoresystem_backen.dto.PageRequest;
import org.example.scoresystem_backen.dto.PageResponse;
import org.example.scoresystem_backen.mapper.StudentMapper;
import org.example.scoresystem_backen.mapper.ScoreMapper;
import org.example.scoresystem_backen.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.HashMap;

/**
 * 学生服务实现类
 */
@Service
@Transactional
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private ScoreMapper scoreMapper;
    
    @Override
    public Student login(String sno, String password) {
        Student student = studentMapper.findBySnoAndPassword(sno, password);
        if (student != null) {
            return student;
        }
        throw new RuntimeException("学号或密码错误");
    }
    
    @Override
    public Student createStudent(Student student) {
        // 检查学号是否已存在
        if (studentMapper.existsBySno(student.getSno())) {
            throw new RuntimeException("学号已存在");
        }
        studentMapper.insert(student);
        return student;
    }
    
    @Override
    public Student updateStudent(Student student) {
        // 检查学生是否存在
        Student existingById = studentMapper.findById(student.getId());
        if (existingById == null) {
            throw new RuntimeException("学生不存在");
        }

        // 检查学号是否被其他学生使用
        Student existingStudent = studentMapper.findBySno(student.getSno());
        if (existingStudent != null && !existingStudent.getId().equals(student.getId())) {
            throw new RuntimeException("学号已被其他学生使用");
        }

        studentMapper.update(student);
        return student;
    }
    
    @Override
    public void deleteStudent(Integer id) {
        Student student = studentMapper.findById(id);
        if (student == null) {
            throw new RuntimeException("学生不存在");
        }

        // 先删除相关的成绩记录
        scoreMapper.deleteByStudentId(id);

        // 再删除学生记录
        studentMapper.deleteById(id);
    }

    @Override
    public Map<String, Object> deleteStudentWithStats(Integer id) {
        Student student = studentMapper.findById(id);
        if (student == null) {
            throw new RuntimeException("学生不存在");
        }

        // 先统计要删除的成绩数量
        Long scoreCount = scoreMapper.countByStudentId(id);

        // 删除相关的成绩记录
        int deletedScores = scoreMapper.deleteByStudentId(id);

        // 删除学生记录
        studentMapper.deleteById(id);

        // 返回删除统计信息
        Map<String, Object> result = new HashMap<>();
        result.put("student_id", id);
        result.put("deleted_scores_count", deletedScores);

        return result;
    }
    
    @Override
    @Transactional(readOnly = true)
    public Student findById(Integer id) {
        Student student = studentMapper.findById(id);
        if (student != null) {
            return student;
        }
        throw new RuntimeException("学生不存在");
    }
    
    @Override
    @Transactional(readOnly = true)
    public Student findBySno(String sno) {
        Student student = studentMapper.findBySno(sno);
        if (student != null) {
            return student;
        }
        throw new RuntimeException("学生不存在");
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Student> findAll() {
        return studentMapper.findAll();
    }

    @Override
    @Transactional(readOnly = true)
    public Page<Student> findAll(Pageable pageable) {
        // MyBatis不直接支持分页，这里简化处理
        List<Student> allStudents = studentMapper.findAll();
        int start = (int) pageable.getOffset();
        int end = Math.min((start + pageable.getPageSize()), allStudents.size());
        List<Student> pageContent = allStudents.subList(start, end);
        return new PageImpl<>(pageContent, pageable, allStudents.size());
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Student> findByClassId(Integer classId) {
        return studentMapper.findByClassId(classId);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Student> findByName(String name) {
        return studentMapper.findByName(name);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Student> findByNameContaining(String name) {
        return studentMapper.findByNameContaining(name);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Student> findBySnoContaining(String sno) {
        return studentMapper.findBySnoContaining(sno);
    }



    @Override
    @Transactional(readOnly = true)
    public boolean existsBySno(String sno) {
        return studentMapper.existsBySno(sno);
    }

    @Override
    @Transactional(readOnly = true)
    public Long countByClassId(Integer classId) {
        return studentMapper.countByClassId(classId);
    }
    
    @Override
    public boolean changePassword(Integer id, String oldPassword, String newPassword) {
        Student student = studentMapper.findById(id);
        if (student != null) {
            if (student.getPassword().equals(oldPassword)) {
                student.setPassword(newPassword);
                studentMapper.update(student);
                return true;
            } else {
                throw new RuntimeException("原密码错误");
            }
        }
        throw new RuntimeException("学生不存在");
    }

    @Override
    @Transactional(readOnly = true)
    public PageResponse<StudentWithClassDTO> findStudentsWithClassByPage(PageRequest pageRequest) {
        pageRequest.validate();

        // 查询数据
        List<StudentWithClassDTO> students = studentMapper.findStudentsWithClassByPage(
            pageRequest.getSearch(),
            pageRequest.getClassId(),
            pageRequest.getOffset(),
            pageRequest.getLimit()
        );

        // 查询总数
        Long totalCount = studentMapper.countStudentsWithFilter(
            pageRequest.getSearch(),
            pageRequest.getClassId()
        );

        return PageResponse.of(pageRequest, totalCount, students);
    }
}
